/**
 * Classe gérant les événements de l'interface
 * @author Marie-Hélène Goddet, Damien Finck, Cédric Schaller
 * 
 */
package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;

import utils.Debug;
import fastwriting.Choix;
import fastwriting.Dico;
import fastwriting.FastWriting;

public class Evenements implements ActionListener, MouseListener, MouseMotionListener, CaretListener {
	
	static boolean DEBUG=false;
	static boolean REPAINT=true;
	
	IHM ihm;
	Dico dico;
	static Point last; // dernière position
	
	static Vector<Point> v; // \__ Algorithme de boucle sur l'écran
	static int cpt=0;       // /
	
	static Point c1,c2,c3,c4; // Algorithme de changement de direction sur une touche
	
	static boolean isChanged=false;//pour effacer la liste de choix
	static boolean swyping=false;//pour supprimer des effets de bords
	static Choix choice;
	
	/** Constructeurs **/
	public Evenements(IHM ihm,Dico dico) {
		this.ihm=ihm;
		this.dico=dico;
		v =new Vector<Point>();// Algorithme de boucle sur l'écran
		c1 = new Point(-1,-1);// \\
		c2 = new Point(-1,-1);//  ||---- Algorithme de changement de direction sur une touche
		c3 = new Point(-1,-1);//  ||
		c4 = new Point(-1,-1);// //
	}
	
	/** ActionListener **/
	@Override
	public void actionPerformed(ActionEvent arg0) {
		int start,end;
		Object obj = arg0.getSource();
		if (obj instanceof JTouche) {
			JTouche jt = (JTouche)obj;
			if (jt.getMode()==JTouche.TOUCHE_STANDARD) { /* Appuie sur touche standard */
				if (!ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()) {	// En mode "Ecriture de messages"
					start=ihm.jscreen.jta_ecran.getSelectionStart();
					end=ihm.jscreen.jta_ecran.getSelectionEnd();
					try {
						ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
						ihm.jscreen.jta_ecran.getDocument().insertString(ihm.jscreen.jta_ecran.getCaretPosition(),jt.getText(),null);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				} else if (ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()){	// En mode "Dico perso"
					if (ihm.jdico.jtf_ajout.hasFocus()) {
						start=ihm.jdico.jtf_ajout.getSelectionStart();
						end=ihm.jdico.jtf_ajout.getSelectionEnd();
						try {
							ihm.jdico.jtf_ajout.getDocument().remove(start, end-start);
							ihm.jdico.jtf_ajout.getDocument().insertString(ihm.jdico.jtf_ajout.getCaretPosition(),jt.getText(),null);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					}
				} else {			// En mode "Options"
					if (ihm.joptions.jtf_user_nom.hasFocus()) {
						start=ihm.joptions.jtf_user_nom.getSelectionStart();
						end=ihm.joptions.jtf_user_nom.getSelectionEnd();
						try {
							ihm.joptions.jtf_user_nom.getDocument().remove(start, end-start);
							ihm.joptions.jtf_user_nom.getDocument().insertString(ihm.joptions.jtf_user_nom.getCaretPosition(),jt.getText(),null);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					} else if (ihm.joptions.jtf_user_mail.hasFocus()){
						start=ihm.joptions.jtf_user_mail.getSelectionStart();
						end=ihm.joptions.jtf_user_mail.getSelectionEnd();
						try {
							ihm.joptions.jtf_user_mail.getDocument().remove(start, end-start);
							ihm.joptions.jtf_user_mail.getDocument().insertString(ihm.joptions.jtf_user_mail.getCaretPosition(),jt.getText(),null);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					}
				}
			} else if (jt==ihm.jclavier.jt_backspace) {  /* Appuie sur touche backspace */
				if (!ihm.jclavier.jt_dico.isEnfonce()) {	// En mode "Ecriture de messages"
					if (ihm.jscreen.jta_ecran.getText().length()>0) {
						start=ihm.jscreen.jta_ecran.getSelectionStart();
						end=ihm.jscreen.jta_ecran.getSelectionEnd();
						try {
							if (end-start>0)
								ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
							else if (end-start==0 && ihm.jscreen.jta_ecran.getCaretPosition()>0)
								ihm.jscreen.jta_ecran.getDocument().remove(ihm.jscreen.jta_ecran.getCaretPosition()-1,1);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					}
				} else {									// En mode "Dico perso"
					if (ihm.jdico.jtf_ajout.getText().length()>0) {
						start=ihm.jdico.jtf_ajout.getSelectionStart();
						end=ihm.jdico.jtf_ajout.getSelectionEnd();
						try {
							if (end-start>0)
								ihm.jdico.jtf_ajout.getDocument().remove(start, end-start);
							else if (end-start==0 && ihm.jdico.jtf_ajout.getCaretPosition()>0)
							ihm.jdico.jtf_ajout.getDocument().remove(ihm.jdico.jtf_ajout.getCaretPosition()-1,1);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
					}
				}
			} else if (jt==ihm.jclavier.jt_enter) {  /* Appuie sur touche entrée */
				if (!ihm.jclavier.jt_dico.isEnfonce()) {	// En mode "Ecriture de messages"
					start=ihm.jscreen.jta_ecran.getSelectionStart();
					end=ihm.jscreen.jta_ecran.getSelectionEnd();
					try {
						ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
						ihm.jscreen.jta_ecran.getDocument().insertString(ihm.jscreen.jta_ecran.getCaretPosition(),"\n",null);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				}
			} else if (jt==ihm.jclavier.jt_space) {  /* Appuie sur touche espace */
				if (!ihm.jclavier.jt_dico.isEnfonce()) {
					start=ihm.jscreen.jta_ecran.getSelectionStart();
					end=ihm.jscreen.jta_ecran.getSelectionEnd();
					try {
						ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
						ihm.jscreen.jta_ecran.getDocument().insertString(ihm.jscreen.jta_ecran.getCaretPosition()," ",null);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				} else {
					start=ihm.jdico.jtf_ajout.getSelectionStart();
					end=ihm.jdico.jtf_ajout.getSelectionEnd();
					try {
						ihm.jdico.jtf_ajout.getDocument().remove(start, end-start);
						ihm.jdico.jtf_ajout.getDocument().insertString(ihm.jdico.jtf_ajout.getCaretPosition()," ",null);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				}
			} else if (jt==ihm.jclavier.jt_dico) {  /* Appuie sur touche Dico */
				if (ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()) {
					ihm.jscreen.setVisible(false);
					ihm.remove(ihm.jscreen);
					ihm.jdico.setVisible(true);
					ihm.jgeneral.add(ihm.jdico,BorderLayout.NORTH);
					//ihm.repaint();
					ihm.jdico.jtf_ajout.requestFocus();
				} else if (!ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()) {
					ihm.jdico.setVisible(false);
					ihm.remove(ihm.jdico);
					ihm.jscreen.setVisible(true);
					ihm.jgeneral.add(ihm.jscreen,BorderLayout.NORTH);
					//ihm.repaint();
					ihm.jscreen.jta_ecran.requestFocus();
				} else {
					ihm.jclavier.jt_dico.setEnfonce(false);//pas accès à ce mode car JOptions ouvert
				}
			} else if (jt==ihm.jclavier.jt_options) {  /* Appuie sur touche Options */
				if (ihm.jclavier.jt_options.isEnfonce() && !ihm.jclavier.jt_dico.isEnfonce()) {
					ihm.jscreen.setVisible(false);
					ihm.remove(ihm.jscreen);
					ihm.joptions.setVisible(true);
					ihm.jgeneral.add(ihm.joptions,BorderLayout.NORTH);
					//ihm.repaint();
				} else if (!ihm.jclavier.jt_options.isEnfonce() && !ihm.jclavier.jt_dico.isEnfonce()) {
					ihm.joptions.setVisible(false);
					ihm.remove(ihm.joptions);
					ihm.jscreen.setVisible(true);
					ihm.jgeneral.add(ihm.jscreen,BorderLayout.NORTH);
					//ihm.repaint();
					ihm.jscreen.jta_ecran.requestFocus();
				} else {
					ihm.jclavier.jt_options.setEnfonce(false);//pas accès a ce mode car JDico ouvert
				}
			}
		} else if (obj instanceof JMenuItem) {
			JMenuItem jmi = (JMenuItem)obj;
			
			start = ihm.jscreen.jta_ecran.getSelectionStart();
			end = ihm.jscreen.jta_ecran.getSelectionEnd();
			String mot; //Le mot a traiter
			
			try {
				mot = ihm.jscreen.jta_ecran.getDocument().getText(start, end-(start));
				
				if (jmi==ihm.jmi_cancel) {
					ihm.jscreen.jta_ecran.setSelectionStart(ihm.jscreen.jta_ecran.getCaretPosition());
					ihm.jscreen.jta_ecran.setSelectionEnd(ihm.jscreen.jta_ecran.getCaretPosition());
					//nothing
				} else if (jmi==ihm.jmi_dico) {
					dico.ajouterMot(mot);
					ihm.jdico.lm_dico.addElement(mot);
				} else if (jmi==ihm.jmi_lower) {
					ihm.jscreen.jta_ecran.replaceRange(mot.toLowerCase(),start,end);
				} else if (jmi==ihm.jmi_upper) {
					ihm.jscreen.jta_ecran.replaceRange(mot.toUpperCase(),start,end);
				} else if (jmi==ihm.jmi_first) {
					ihm.jscreen.jta_ecran.replaceRange(mot.toUpperCase().substring(0, 1),start,start+1);
					ihm.jscreen.jta_ecran.replaceRange(mot.toLowerCase().substring(1,mot.length()),start+1,end);
				} else if (jmi==ihm.jmi_cut) {
					//end = (end == ihm.jscreen.jta_ecran.getDocument().getLength())?end:end+1; //Supprime l espace si on est pas a la fin
					ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
					try {
						StringSelection ss = new StringSelection(mot);
						Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,null);
					} catch(IllegalStateException e) {
						e.printStackTrace();
						/** Le presse-papier n'est peut-être pas disponible */
					}
				} else if (jmi==ihm.jmi_copy) {
					 //ihm.pressePapier = mot;
					try {
						StringSelection ss = new StringSelection(mot);
						Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,null);
					} catch(IllegalStateException e) {
						e.printStackTrace();
						/** Le presse-papier n'est peut-être pas disponible */
					}
				} else if (jmi==ihm.jmi_paste) {
					//ihm.jscreen.jta_ecran.insert(ihm.pressePapier,ihm.jscreen.jta_ecran.getCaretPosition());
					/** Lecture du contenu : */
					Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
					try {
						/** Vérification que le contenu est de type texte. */
						if( t!=null && t.isDataFlavorSupported(DataFlavor.stringFlavor) ) {
							String txt = (String)t.getTransferData(DataFlavor.stringFlavor);
							
							//ihm.jscreen.jta_ecran.insert(txt,ihm.jscreen.jta_ecran.getCaretPosition());
							
							start=ihm.jscreen.jta_ecran.getSelectionStart();
							end=ihm.jscreen.jta_ecran.getSelectionEnd();
							try {
								ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
								ihm.jscreen.jta_ecran.getDocument().insertString(ihm.jscreen.jta_ecran.getCaretPosition(),txt,null);
							} catch (BadLocationException e) {
								e.printStackTrace();
							}
							
						} 
					} catch(UnsupportedFlavorException e1) {
						e1.printStackTrace();
					} catch(IOException e2) {
						e2.printStackTrace();
					} catch(IllegalStateException e3) {
						e3.printStackTrace();
					/** Le presse-papier n'est peut-être pas disponible */
					}
				} else if (jmi==ihm.jmi_delete) {
					end = (end == ihm.jscreen.jta_ecran.getDocument().getLength())?end:end+1; //Supprime l espace si on est pas a la fin
					ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
				} else if (jmi==ihm.jmi_selectAll) {
					ihm.jscreen.jta_ecran.setSelectionStart(0);
					ihm.jscreen.jta_ecran.setSelectionEnd(ihm.jscreen.jta_ecran.getDocument().getLength());
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		} else if (obj instanceof JButton) {
			JButton jb =(JButton)obj;
			if (jb==ihm.jscreen.jb_left) {
				if (REPAINT) {
					Fonctions.affichage_proposition(ihm,Evenements.choice,true); // affichage les propositions
				}
			} else if (jb==ihm.jscreen.jb_right) {
				if (REPAINT) {
					Fonctions.affichage_proposition(ihm,Evenements.choice,false); // affichage les propositions
				}
			}
			ihm.jscreen.jta_ecran.requestFocus();	// curseur placé dans l'écran
		} else if (obj instanceof JMot) {
			isChanged=true;
			JMot jm = (JMot)obj;
			String text = ihm.jscreen.jta_ecran.getText();
			int finMot = ihm.jscreen.jta_ecran.getCaretPosition();

			int tmp1 = text.substring(0,ihm.jscreen.jta_ecran.getCaretPosition()).lastIndexOf(' ');
			int tmp2 = text.substring(0,ihm.jscreen.jta_ecran.getCaretPosition()).lastIndexOf('\n');
			int tmp3 = text.substring(0,ihm.jscreen.jta_ecran.getCaretPosition()).lastIndexOf('.');
			int debutMot = Math.max(tmp1,Math.max(tmp2,tmp3));
			ihm.jscreen.jta_ecran.replaceRange(jm.getText(), debutMot+1, finMot);
		}
	}
	
	/** CaretListener **/
	@Override
	public void caretUpdate(CaretEvent e) {
		if (!isChanged) {
			//Fonctions.clear_propositions(ihm);
		}
		isChanged=false;
	}
	
	/** MouseListener **/
	@Override
	public void mouseClicked(MouseEvent arg0) {
		
	}
	@Override
	public void mouseEntered(MouseEvent arg0) {
		Object obj = arg0.getSource();
		v.clear();cpt=0;
		if (obj instanceof JPanel) {
			JPanel jp = (JPanel)obj;
			if (jp==ihm.jgeneral) {
				if (arg0.getModifiers()==16 && ihm.jclavier.jt_specialChar.getText().contains("@")) {
					c2.x=c4.x;
					c2.y=c4.y;
					Point p4 = Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
					c4.x=p4.x;//getX_relativeToIHM(arg0,jt);
					c4.y=p4.y;//getY_relativeToIHM(arg0,jt);
					// Algorithme de changement de direction sur une touche
					Fonctions.changeDirection(c1,c2,c3,c4);
					
					if (Debug.DEBUG && Debug.TAG.contains("changedirection")) {
						Graphics g = ihm.getGraphics();
						g.setColor(Color.BLACK);
						g.drawOval(c4.x, c4.y, 6, 6);
					}
				}
			}
		} else if (obj instanceof JTouche) {
			JTouche jt = (JTouche) obj;
			if (arg0.getModifiers()==16 && ihm.jclavier.jt_specialChar.getText().contains("@")) {
				c2.x=c4.x;
				c2.y=c4.y;
				Point p4 = Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
				c4.x=p4.x;//getX_relativeToIHM(arg0,jt);
				c4.y=p4.y;//getY_relativeToIHM(arg0,jt);
				// Algorithme de changement de direction sur une touche
				Fonctions.changeDirection(c1,c2,c3,c4);
				
				if (Debug.DEBUG && Debug.TAG.contains("changedirection")) {
					Graphics g = ihm.getGraphics();
					g.setColor(Color.BLACK);
					g.drawOval(c4.x, c4.y, 6, 6);
				}
			}
		}
	}
	@Override
	public void mouseExited(MouseEvent arg0) {
		Object obj = arg0.getSource();
		v.clear();cpt=0;
		if (obj instanceof JPanel) {
			JPanel jp = (JPanel)obj;
			if (jp==ihm.jgeneral) {
				if (arg0.getModifiers()==16 && ihm.jclavier.jt_specialChar.getText().contains("@")) {
					// Algorithme de changement de direction sur une touche
					c1.x=c3.x;
					c1.y=c3.y;
					Point p3 = Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
					c3.x=p3.x;//getX_relativeToIHM(arg0,jt);
					c3.y=p3.y;//getY_relativeToIHM(arg0,jt);
					if (Debug.DEBUG && Debug.TAG.contains("changedirection")) {
						Graphics g = ihm.getGraphics();
						g.setColor(Color.BLUE);
						g.drawOval(c3.x, c3.y, 6, 6);
					}
				}
			}
		} else if (obj instanceof JTouche) {
			JTouche jt = (JTouche) obj;
			if (arg0.getModifiers()==16 && ihm.jclavier.jt_specialChar.getText().contains("@")) {
				// Algorithme de changement de direction sur une touche
				c1.x=c3.x;
				c1.y=c3.y;
				Point p3 = Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
				c3.x=p3.x;//getX_relativeToIHM(arg0,jt);
				c3.y=p3.y;//getY_relativeToIHM(arg0,jt);
				if (Debug.DEBUG && Debug.TAG.contains("changedirection")) {//DELETE@END
					Graphics g = ihm.getGraphics();
					g.setColor(Color.BLUE);
					g.drawOval(c3.x, c3.y, 6, 6);
				}
			}
		}
	}
	@Override
	public void mousePressed(MouseEvent arg0) {
		Fonctions.clear_propositions(ihm);
		// Intialisation
		Point crt = new Point(-1,-1);
		Color couleur=Color.BLACK;
		// Différence entre IHM_FastWriting et JTouche
		Object obj = arg0.getSource();
		if (obj instanceof JPanel) {
			JPanel jp = (JPanel)obj;
			if (jp==ihm.jgeneral) {
				// paramètres de IHM_FastWriting
				crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
				couleur=Color.BLUE;
			}
		} else if (obj instanceof JTouche) {
			JTouche jt = (JTouche) obj;
			// paramètres de JTouche
			crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
			couleur=Color.BLUE;
			if (jt.getMode()==JTouche.TOUCHE_STANDARD) {
			//	FastWriting.wordWriting.add(jt.getText().charAt(0));
			} else {//différents cas de touches spéciales
				
			}
		}
		// au clic pressed, je change de curseur, et j'active l'écriture
		ihm.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		// je dessine le point
		Graphics g = ihm.getGraphics();
		Fonctions.dessinerPoint(g,couleur,crt);
		// Je sauvegarde le dernier point (pour tracer une ligne au point suivant)
		last=crt;
	}
	@Override
	public void mouseReleased(MouseEvent arg0) {
		swyping=false;
		v.clear();cpt=0;
		// Intialisation
		Point crt = new Point(-1,-1);
		Color couleur=Color.BLACK;
		// Différence entre IHM_FastWriting et JTouche
		Object obj = arg0.getSource();
		if (obj instanceof JPanel) {
			JPanel jp = (JPanel)obj;
			if (jp==ihm.jgeneral) {
				crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
				couleur=Color.PINK;
			}
		} else if (obj instanceof JTouche) {
			JTouche jt = (JTouche) obj;
			// paramètres de JTouche
			crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
			couleur=Color.MAGENTA;
		}
		// au clic released, je change de curseur, et de désactive l'écriture
		ihm.setCursor(new Cursor(Cursor.HAND_CURSOR));
		// je dessine le point
		Graphics g = ihm.getGraphics();
		Fonctions.dessinerPoint(g,couleur,crt);
		//drawPoint(g,couleur,event_x,event_y);
		// le dernier point en mis à -1
		last = new Point(-1,-1);
		//je valide le mot
		if (!FastWriting.wordWriting.isVide() && ihm.jclavier.jt_specialChar.getText().contains("@") && !ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()) {
			
			if (FastWriting.wordWriting.toString().toLowerCase().charAt(0)>='a' && FastWriting.wordWriting.toString().toLowerCase().charAt(0)<='z')
			{
				//a la fin de la swypification, on enregistre les possibilités qu'on ait fini pas sur la bonne lettre
				List<Character> near_end = new ArrayList<Character>();
				for (int x = -70;x<=70;x+=70){
					for (int y = -60;y<=60;y+=60){
						Component c =ihm.findComponentAt(crt.x+x,crt.y+y);
						if (c instanceof JTouche){
							JTouche jt = (JTouche)c;
							if (jt.getMode()==JTouche.TOUCHE_STANDARD) {
								near_end.add(Character.toLowerCase(jt.getText().charAt(0)));
							}
						}
					}
				}
				
				FastWriting.wordWriting.addPossibleEnd(near_end);
				choice = new Choix();
				String bestWord=choice.getBest(FastWriting.wordWriting, dico);
				
				
				String s="";
				int longueur=ihm.jscreen.jta_ecran.getDocument().getLength();
				int start=ihm.jscreen.jta_ecran.getSelectionStart();
				int end=ihm.jscreen.jta_ecran.getSelectionEnd();
				
				try {
					if ( longueur==0 || 
							ihm.jscreen.jta_ecran.getDocument().getText(longueur-1, 1).equals("\n") ||
							ihm.jscreen.jta_ecran.getDocument().getText(longueur-1, 1).equals(" ") ) s="";
					else s=" ";
					
					ihm.jscreen.jta_ecran.getDocument().remove(start, end-start);
					ihm.jscreen.jta_ecran.getDocument().insertString(ihm.jscreen.jta_ecran.getCaretPosition(),s+bestWord,null);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
				
				if (REPAINT) Fonctions.affichage_proposition(ihm,choice,true); // affichage les propositions
			}
		}
		printAlgoCentreTouche();
		
		FastWriting.wordWriting.clear();
		
		ihm.jclavier.jt_maj.setEnfonce(false);
		ihm.jclavier.jt_maj.setLock(false);
		ActionEvent e = new ActionEvent(ihm.jclavier.jt_maj,1001,"JClavier_xxx");
		ihm.jclavier.jt_maj.getActionListener().actionPerformed(e);
		//END algo "boucleEcran"
		//START algo "changeDirection"
		c1 = new Point(-1,-1);
		c2 = new Point(-1,-1);
		c3 = new Point(-1,-1);
		c4 = new Point(-1,-1);
		//END algo "changeDirection"
		
		if (REPAINT) ihm.repaint();
	}
	
	/** MouseMotionListener **/
	@Override
	public void mouseDragged(MouseEvent arg0) {
		if (ihm.jclavier.jt_specialChar.getText().contains("@") && !ihm.jclavier.jt_dico.isEnfonce() && !ihm.jclavier.jt_options.isEnfonce()) {
			swyping=true;
			// Intialisation
			Point crt = new Point(-1,-1);
			// Différence entre IHM_FastWriting et JTouche
			Object obj = arg0.getSource();
			if (obj instanceof JPanel) {
				JPanel jp = (JPanel)obj;
				if (jp==ihm.jgeneral) {
					
					// paramètres de IHM_FastWriting
					crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
				
					// je cherche le composant au coordonnées
					Component c =ihm.findComponentAt(crt.x,crt.y);
					if (c instanceof JTouche) {
						JTouche jt_survol = (JTouche)c;
						if (jt_survol.getMode()==JTouche.TOUCHE_STANDARD) {//if (!jt_survol.isToucheSpecial() /*&& modeWriting*/) {
							Fonctions.swype_letter(ihm,jt_survol,crt);
							Fonctions.algo_boucle(ihm, crt, v, cpt,arg0,jt_survol);//algo de la boucle
						}
						
					} else {
						Fonctions.algo_boucle(ihm, crt, v, cpt);//algo de la boucle
					}
				
				}
			} else if (obj instanceof JTouche) {
				JTouche jt = (JTouche) obj;
				// paramètres de JTouche
				crt=Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
				
				// je cherche le composant au coordonnées
				Component c = ihm.findComponentAt(crt.x,crt.y);
				if (c instanceof JTouche) {
					JTouche jt_survol = (JTouche)c;
					if (jt_survol.getMode()==JTouche.TOUCHE_STANDARD) {
						Fonctions.swype_letter(ihm,jt_survol,crt);
						Fonctions.algo_boucle(ihm, crt, v, cpt,arg0,jt_survol);//algo de la boucle
					} else if (jt_survol==ihm.jclavier.jt_backspace) {
						Fonctions.algo_boucle(ihm, crt, v, cpt,arg0,jt_survol);//algo de la boucle
					}
					
				} else {
					Fonctions.algo_boucle(ihm, crt, v, cpt);//algo de la boucle
				}
			}
			// j'affiche les coordonnées du curseur
			affiche_coordonnees(crt);
			if (ihm.jclavier.jt_specialChar.getText().contains("@")) {
				// je dessine la ligne
				Graphics g = ihm.getGraphics();
				Fonctions.dessinerLigne(g,last,crt);
			}
			// Je sauvegarde le dernier point (pour tracer une ligne au point suivant)
			last=crt;
		}
	}
	@Override
	public void mouseMoved(MouseEvent arg0) {
		// Intialisation
		Point crt = new Point(-1,-1);
		// Différence entre IHM_FastWriting et JTouche
		Object obj = arg0.getSource();
		if (obj instanceof JPanel) {
			JPanel jp = (JPanel)obj;
			if (jp==ihm.jgeneral) {
				// paramètres de IHM_FastWriting
				crt = Fonctions.getPoint_relativeToIHM(ihm,arg0,jp);
			}
		} else if (obj instanceof JTouche) {
			JTouche jt = (JTouche) obj;
			// paramètres de JTouche
			crt = Fonctions.getPoint_relativeToIHM(ihm,arg0,jt);
		}
		// j'affiche les coordonnées du curseur
		affiche_coordonnees(crt);
	}
	
	
	/************* En dessous de cette ligne : c'est TEST *******************************************/
	public void printAlgoCentreTouche() {
		Debug.addLog("Info au mouseReleased()", Debug.LOG_INFO, "centreTouche");
		if (Debug.DEBUG && Debug.TAG.contains("centretouche")) {
			for (int i=0;i<FastWriting.wordWriting.size();i++) {
				System.out.println("["+FastWriting.wordWriting.getLettre(i).getCar()+"]="+FastWriting.wordWriting.getLettre(i).getCentreTouche());
			}
		}
	}
	public void affiche_coordonnees(Point p) {
		ihm.jscreen.jl_position.setText("(x="+p.getX()+";y="+p.getY()+")");
	}
}